package com.smile.config.mybatis;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.session.ResultHandler;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.Statement;
import java.util.Properties;

//@Intercepts({
//    @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
// 可以添加更多需要拦截的方法
//})
@Component
@Slf4j
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}),
        @Signature(type = StatementHandler.class, method = "update", args = {Statement.class})
})
public class CustomExecutorInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 1.在执行update方法前的操作
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
        BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
        // 打印 SQL 语句
        String sql = boundSql.getSql();
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
        log.info("Executing SQL: [" + mappedStatement.getId() + "] => " + sql);


        // 2.调用原来的方法
        Object result = invocation.proceed();
        // 3.在执行update方法后的操作

        return result;
    }

    @Override
    public Object plugin(Object target) {
        // 返回一个代理对象，使得目标对象的方法调用可以被拦截器拦截
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        // 设置拦截器的属性
    }
}
